#pragma once

#include <iostream>
#include <pthread.h>
#include <string>
#include <cstring>
#include <assert.h>
#include <functional>

class Thread;

// 上下文
class Context
{
public:
    Thread *this_;
    void *args_;

public:
    Context() : this_(nullptr), args_(nullptr)
    {
    }
    ~Context()
    {
    }
};

class Thread
{
public:
    typedef std::function<void *(void *)> func_t;
    const int num = 1024;

public:
    Thread(func_t func, void *args, int number)
        : func_(func), args_(args)
    {
        // name_+="thread-";
        // name_+=std::to_string(number); //C和C++混编,一般系统编程不识别string

        char buffer[num];
        snprintf(buffer, sizeof buffer, "thread-%d", number);
        name_ = buffer;

        Context *ctx = new Context();
        ctx->this_ = this;
        ctx->args_ = args_;
        int n = pthread_create(&tid_, nullptr, start_routine, (void *)ctx); // func_不能直接调用，要C++转C
        assert(n == 0);
        (void)n;
    }

    static void *start_routine(void *args) // 类内非静态有this指针
    {
        Context *ctx = static_cast<Context *>(args);
        // 静态方法不能调用成员变量 错误：return func_(args);
        void *ret = ctx->this_->run(ctx->args_);
        delete ctx;
        return ret;
    }

    //void start()
    //{
    //    Context *ctx = new Context();
    //    ctx->this_ = this;
    //    ctx->args_ = args_;
    //    int n = pthread_create(&tid_, nullptr, start_routine, ctx); // func_不能直接调用，要C++转C
    //    assert(n == 0);
    //    (void)n;
    //}

    void join()
    {
        int n = pthread_join(tid_, nullptr); // func_不能直接调用，要C++转C
        assert(n == 0);
        (void)n;
    }

    void *run(void *args)
    {
        return func_(args);
    }

    ~Thread()
    {
        // do nothing
    }

private:
    std::string name_;
    func_t func_;
    void *args_;

    pthread_t tid_;
};